package com.mind.core.server;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Set;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.NotFoundException;

import org.scannotation.AnnotationDB;
import org.scannotation.ClasspathUrlFinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bugull.mongo.annotations.Entity;
import com.bugull.mongo.annotations.Id;
import com.bugull.mongo.annotations.Ignore;
import com.mind.core.handler.MessageHandler;
import com.mind.core.net.handler.HandlerManager;
import com.mind.core.net.msg.BaseMessage;
import com.mind.core.net.msg.Message;
import com.mind.core.util.StringUtils;

public class GameLoader {
	private static final Logger logger = LoggerFactory.getLogger(GameLoader.class);
	private static GameLoader gameLoader=new GameLoader();
	public static GameLoader getInstance(){
		return gameLoader;
	}
	
	
	public void dealCodec() throws Exception{
		ClassPool classPool=ClassPool.getDefault();
		AnnotationDB annotationDB=new AnnotationDB();
		try {
			annotationDB.scanArchives(ClasspathUrlFinder.findClassPaths());
		} catch (IOException e) {
			logger.error("", e);
		}
		loadMessage(annotationDB, classPool);
	}
	private void loadMessage(AnnotationDB annotationDB,ClassPool classPool) throws Exception{
		Set<String> entities=annotationDB.getSubClass(MessageHandler.class.getName());
		for(String name:entities){
			Class class1=Class.forName(name);
			Method method=class1.getDeclaredMethod("getTypes");
			if(method!=null){
				MessageHandler  handler=(MessageHandler) class1.newInstance();
				HandlerManager.register(handler);
			}
		}
		entities=annotationDB.getSubClass(BaseMessage.class.getName());
		for(String name:entities){
			CtClass class1=	classPool.get(name);
			CtMethod method=class1.getDeclaredMethod("getMessageType");
			if(method!=null){
				Class class2=Class.forName(name);
				HandlerManager.register((Class<? extends Message>)class2);
			}
		}
	}
	/**
	 * 将所有数据库实体增加 fieldChange的代码
	 */
	private  void addChangeFields(AnnotationDB annotationDB,ClassPool classPool){
		try {
			Set<String> entities=annotationDB.getAnnotationIndex().get(Entity.class.getName());
			for(String name:entities){
				CtClass class1=	classPool.get(name);
				CtField[] fields=	class1.getDeclaredFields();
				for(CtField field:fields){
					if(field.getAnnotation(Id.class)!=null
							||field.getAnnotation(Ignore.class)!=null){
						continue;
					}
					CtMethod method=class1.getDeclaredMethod("set"+StringUtils.toUpperCaseFirstOne(field.getName()));
					if(method!=null){
						String src="		changeFields.put(\""+field.getName()+"\",this."+field.getName()+");";
						method.insertAfter(src,true);
					}
				}
			}
		} catch (NotFoundException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CannotCompileException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
